package cn.jofei.netty.hadler;

import cn.jofei.common.enums.Headers;
import cn.jofei.common.monitor.msg.DingMsg;
import cn.jofei.server.http.filter.HttpRequestFilter;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * HttpProxyClientHandler
 *
 * @author Jofei Bao
 * @version ngbao v1.0.
 * @date 2022年10月17日 23:03
 */
@Data
public class HttpServerHandler extends ChannelInboundHandlerAdapter {

    private final Logger logger = LoggerFactory.getLogger(HttpServerHandler.class);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
            request.headers().add(Headers.X_Real_IP, address.getHostName());
            // 停止当前通道的读取，直到客户端远程通道建立
            ctx.channel().config().setAutoRead(false);
            for (HttpRequestFilter requestFilter : getHttpFilterChain()) {
                if (requestFilter.doFilter(request, ctx)) {
                    break;
                }
            }
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        flushAndClose(ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        DingMsg.markdown("Ngbao监控").text(String.format("#### Ngbao监控\n#### HTTP服务异常\n##### 原因：%s", cause.getMessage())).build().send();
        flushAndClose(ctx.channel());
    }

    private void flushAndClose(Channel ch) {
        if (ch != null && ch.isActive()) {
//            ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
            ch.close();
        }
    }

    public List<HttpRequestFilter> getHttpFilterChain() {
        return HttpRequestFilter.FILTER_LIST;
    }
}
